package com.twb.message.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.twb.core.base.entity.BaseLoginUser;
import com.twb.core.base.entity.TwbPageInfo;
import com.twb.core.base.service.impl.BaseService;
import com.twb.core.exception.ServiceException;
import com.twb.core.util.BeanUtils;
import com.twb.core.util.ExcelUtils;
import com.twb.core.util.TwbPageUtil;
import com.twb.message.constants.TwbMessageConstants;
import com.twb.message.entity.message.Message;
import com.twb.message.entity.message.dto.SearchMessageDto;
import com.twb.message.entity.message.dto.SearchToPublishTwbUserDto;
import com.twb.message.entity.message.vo.SaveMessageVo;
import com.twb.message.entity.message.vo.SearchMessageByUserVo;
import com.twb.message.entity.message.vo.SearchMessageVo;
import com.twb.message.entity.message.vo.UpdateMessageByIdVo;
import com.twb.message.entity.messageReceivor.MessageReceivor;
import com.twb.message.entity.messageReceivor.vo.SaveMessageReceivorVo;
import com.twb.message.mapper.MessageMapper;
import com.twb.message.service.IMessageReceivorService;
import com.twb.message.service.IMessageService;
import com.twb.netty.entity.NettyMessage;
import com.twb.netty.handler.NettySendMsgUtil;
import com.twb.system.util.ExcelDataDicHandlerImpl;

/**
 * @ClassName MessageService
 * @Description 系统消息管理service
 * 
 * @author DHL
 * @date 2021-07-14 09:22:28
 */
@Service("messageService")
public class MessageService extends BaseService<MessageMapper,Message> implements IMessageService {

	@Autowired
	MessageMapper messageMapper;

	@Autowired
	IMessageReceivorService messageReceivorService;
	
	@Override
	public TwbPageInfo<SearchMessageDto> searchMessage(SearchMessageVo vo) {
		TwbPageUtil.startPage(vo);
		List<SearchMessageDto> list = messageMapper.searchMessage(vo);
		return TwbPageUtil.of(list);
	}

	@Override
	public List<SearchMessageDto> searchMessageList(SearchMessageVo vo) {
		List<SearchMessageDto> list = messageMapper.searchMessage(vo);
		return list;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveMessage(SaveMessageVo vo) {
		Message record = new Message();
		BeanUtils.copyNotNullProperties(vo, record);
		record.setId(this.getUUID());
		this.setCreateInfo(record);
		this.setUpdateInfo(record);

		record.setSendDate(LocalDateTime.now());
		record.setSender(getLoginUser().getName());
		record.setSenderId(getLoginUser().getId());

		if (StringUtils.isBlank(record.getStatus())) {
			record.setStatus("0"); // 暂存待发布
		}
		if(record.getReceivorType().equals(TwbMessageConstants.ReceivorType.company) || record.getReceivorType().equals(TwbMessageConstants.ReceivorType.department) ) {
			record.setReceivorOrgIds(StringUtils.join(vo.getReceivorIds(),","));
		} else {
			record.setReceivorOrgIds(null);
		}
		boolean result = this.save(record);

		if (result) {
			List<String> receivorIds = vo.getReceivorIds();
			this.saveMessageReceivor(record, receivorIds);
			//已发布状态，则发布消息
			if(record.getStatus().equals("1")) {
				this.publish(record);
			}
		}

		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateMessageById(UpdateMessageByIdVo vo) {
		Message record = messageMapper.selectById(vo.getId());
		if (null == record) {
			throw new ServiceException("数据不存在");
		}

		BeanUtils.copyNotNullProperties(vo, record);
		this.setUpdateInfo(record);
		
		record.setSendDate(LocalDateTime.now());
		record.setSender(getLoginUser().getName());
		record.setSenderId(getLoginUser().getId());
		
		if (StringUtils.isBlank(record.getStatus())) {
			record.setStatus("0"); // 暂存待发布
		}
		if(record.getReceivorType().equals(TwbMessageConstants.ReceivorType.company) || record.getReceivorType().equals(TwbMessageConstants.ReceivorType.department) ) {
			record.setReceivorOrgIds(StringUtils.join(vo.getReceivorIds(),","));
		} else {
			record.setReceivorOrgIds(null);
		}
		boolean result = this.updateById(record);
		
		if (result) {
			messageReceivorService.deleteMessageReceivorByMessageId(record.getId());
			List<String> receivorIds = vo.getReceivorIds();
			this.saveMessageReceivor(record, receivorIds);
			//已发布状态，则发布消息
			if(record.getStatus().equals("1")) {
				this.publish(record);
			}
		}
		
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteMessageById(String id) {
		boolean result = this.removeById(id);
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean deleteMessageByIds(String ids) {
		return this.removeByIds(Arrays.asList(ids.split(",")));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int logicBatchDeleteMessageByIds(String ids) {
		List<String> list = new ArrayList<String>();
		Collections.addAll(list, ids.split(","));
		return messageMapper.logicBatchDeleteByIds(list);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void exportExcel(SearchMessageVo vo, HttpServletResponse response) throws Exception {
		TwbPageInfo<SearchMessageDto> pageInfo = this.searchMessage(vo);
		ExcelDataDicHandlerImpl excelDataDicHandlerImpl = new ExcelDataDicHandlerImpl();
		ExcelUtils.exportExcel(vo,"系统消息管理", pageInfo.getList(), SearchMessageDto.class, response,excelDataDicHandlerImpl);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int importExcel(Map<String, String> map) {
		System.out.println(map.toString());
		return 0;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean publish(Message message) {
		List<String> receivorList = new ArrayList<>();
		if(message.getReceivorType().equals(TwbMessageConstants.ReceivorType.company) || message.getReceivorType().equals(TwbMessageConstants.ReceivorType.department) ) {
			if(StringUtils.isBlank(message.getReceivorOrgIds())) {
				throw new ServiceException("请选择接收公司/部门");
			}
			receivorList.addAll(Arrays.asList(message.getReceivorOrgIds().split(",")));
		}
		if(message.getReceivorType().equals(TwbMessageConstants.ReceivorType.user)) {
			MessageReceivor params = new MessageReceivor();
			params.setIsdel(0);
			params.setMessageId(message.getId());
			List<MessageReceivor> list = messageReceivorService.list(params);
			if(list.isEmpty()) {
				throw new ServiceException("请选择接收人");
			}
			for (MessageReceivor messageReceivor : list) {
				receivorList.add(messageReceivor.getReceivorId());
				//更新为已发送
				messageReceivor.setSendStatus("1");
				messageReceivor.setSendDate(LocalDateTime.now());
				messageReceivor.setReadStatus("0");
			}
			messageReceivorService.updateBatchById(list);
		}

		message.setStatus("1");
		this.setUpdateInfo(message);
		boolean result = this.updateById(message);

		if (result) {
			if (CollectionUtils.isNotEmpty(receivorList)) {
				this.sendMessage(message, receivorList);
			}
		}
		return result;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean cancel(String messsageId, String revokeReason) {
		Message message = messageMapper.selectById(messsageId);

		if (message == null) {
			throw new ServiceException("数据不存在");
		}
		
		message.setRevoker(getLoginUser().getName());
		message.setRevokerId(getLoginUser().getId());
		message.setRevokeDate(LocalDateTime.now());
		message.setRevokeReason(revokeReason);
		message.setStatus("2");
		
		this.setUpdateInfo(message);
		boolean result = this.updateById(message);
		
		return result;
	}
	
	
	/**
	 * @Title saveMessageReceivor
	 * @Description 保存消息接收人
	 * @param message 消息对象
	 * @author DHL
	 * @date 2021年7月14日 上午11:23:03
	 */
	private void saveMessageReceivor(Message message, List<String> receivorIds) {
		String receivorType = message.getReceivorType();
		//个人消息处理
		if(TwbMessageConstants.ReceivorType.user.equals(receivorType)) {
			List<SearchToPublishTwbUserDto> list = messageMapper.searchToPublishTwbUser(receivorIds);

			if (list != null) {
				for (SearchToPublishTwbUserDto publishUserDto : list) {
					// 保存发布用户信息
					SaveMessageReceivorVo saveMessageReceivorVo = new SaveMessageReceivorVo();
					saveMessageReceivorVo.setMessageId(message.getId());
					saveMessageReceivorVo.setReceivorId(publishUserDto.getId());
					saveMessageReceivorVo.setReceivor(publishUserDto.getName());
					saveMessageReceivorVo.setReceivorAccount(publishUserDto.getLoginName());
					saveMessageReceivorVo.setSendStatus("0");
					messageReceivorService.saveMessageReceivor(saveMessageReceivorVo);
				}
			}
		}
	}
	
	
	/**
	 * @Title sendMessage
	 * @Description 发布消息
	 * @param message
	 * @param loginNameList
	 * @author DHL
	 * @date 2021年7月16日 上午10:05:52
	 */
	private void sendMessage(Message message, List<String> receivorList) {
		if(message.getStatus().equals("1")) {
			for (String id : receivorList) {
				NettyMessage nettyMessage = new NettyMessage();
				
				nettyMessage.setAppId(message.getProjectId());
				nettyMessage.setSenderUserId(message.getSenderId());
				nettyMessage.setReceiverId(id);
				nettyMessage.setReceiverType(message.getReceivorType());
				nettyMessage.setContent(JSON.toJSONString(message));
				nettyMessage.setType(2);
				
				NettySendMsgUtil.sendMsg(nettyMessage);
			}
		}
	}
	
	
	/**
	 * @Title sendUniPushMessage
	 * @Description 发送uni app消息
	 * @author DHL
	 * @date 2021年9月7日 下午1:47:15
	 */
	/*private void sendUniPushMessage(Message message, List<String> clientIds) {
		PushMessage pushMessage = new PushMessage();
		pushMessage.setTitle("审批消息");
		pushMessage.setContent(message.getTitle());
		
		JSONObject payload = new JSONObject();
		payload.put("bizUrl", message.getBizUrl());
		payload.put("type", PushMessagePayloadTypeEnum.OA.getCode());
		pushMessage.setPayload(payload);
		
		UniPushUtil.pushMessage(pushMessage, clientIds);
	}*/

	@Override
	public TwbPageInfo<SearchMessageDto> searchMessageByUser(SearchMessageByUserVo vo) {
		TwbPageUtil.startPage(vo);
		List<SearchMessageDto> list = messageMapper.searchMessageByUser(vo);
		return TwbPageUtil.of(list);
	}

	@Override
	public boolean readMessage(Message message) {
		String receivorType = message.getReceivorType();
		//如果是个人消息，则更新阅读状态
		if(receivorType.equals(TwbMessageConstants.ReceivorType.user)) {
			MessageReceivor messageReceivorVo = new MessageReceivor();
			messageReceivorVo.setMessageId(message.getId());
			messageReceivorVo.setReceivorId(getLoginUser().getId());
			MessageReceivor messageReceivor = messageReceivorService.getOne(messageReceivorVo);

			messageReceivor.setReadStatus("1");
			messageReceivor.setReadDate(LocalDateTime.now());

			return messageReceivorService.updateById(messageReceivor);
		}else {//如果是部门或者公司消息，阅读后则插入阅读人信息
			BaseLoginUser loginUser = getLoginUser();
			MessageReceivor messageReceivor = new MessageReceivor();
			messageReceivor.setMessageId(message.getId());
			messageReceivor.setReceivorId(loginUser.getId());
			messageReceivor.setReceivor(loginUser.getName());
			messageReceivor.setReceivorAccount(loginUser.getLoginName());
			messageReceivor.setSendStatus("1");
			messageReceivor.setSendDate(message.getSendDate());
			messageReceivor.setReadStatus("1");
			messageReceivor.setReadDate(LocalDateTime.now());
			messageReceivorService.setCreateInfo(messageReceivor);
			return messageReceivorService.save(messageReceivor);
		}
	}
}
